﻿using GalaSoft.MvvmLight;
using System.Windows.Input;
using System.Collections.Generic;
using GalaSoft.MvvmLight.Messaging;
using System.Collections.ObjectModel;
using System.Threading;
using ASoft.Service;
using ASoft.Msg;
using System;
using ASoft.Data;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ASoft.Base;


namespace ASoft.WPF.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase, IDataObserver
    {

        MsgReceivedEventHandler msgReceivedEventHandler;

        HttpPostService httpPostService = new HttpPostService();
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            if (IsInDesignMode)
            {
                _Tops = new List<ViewModelBase>();
            }
            else
            {
                msgReceivedEventHandler = new MsgReceivedEventHandler(MsgService_MsgReceived);
                RC.Current.MsgService.MsgReceived += msgReceivedEventHandler;
                RC.Current.RootData.AddtObserver(this);
                Messenger.Default.Register<MessageBase>(this,
                                                "Reload温室实时数据集合",
                                                (a) => this.Reload温室实时数据集合());

            }
        }

        void MsgService_MsgReceived(object sender, MsgReceiveEventArgs e)
        {
            if (e.IsValid && (e.Msg is RoomReturnSearchMsg || e.Msg is PhecReturnSearch))
            {
                byte id = (byte)e.Msg.GetType().GetProperty("Id").GetValue(e.Msg, null);
                foreach (var item in 温室实时数据集合)
                {

                    if (item.Id == id)
                    {
                        WPFUtility.TransFromDataToViewModel(e.Msg, item.温室实时数据);
                        item.实时数据最后更新时间 = DateTime.Now;
                        item.检测结果 = ECheckFlag.成功;
                        RC.Current.RoomLastMsgs[item.Id] = e.Msg;
                        SendHttpPost(e.Msg, id);

                        LogText = string.Format("读取{0}.{1}成功", item.Id, item.RoomName);
                    }
                }
                if (RC.Current.RootData.启用模似气象站)
                {
                    SendHttpPost(RC.Current.RootData.气象站模似信息);
                }
            }
            else if (e.IsValid && e.Msg is WeatherStationReturnMsgBase)
            {
                var m = (WeatherStationReturnMsgBase)e.Msg;
                RC.Current.RootData.气象站实时信息 = m;
                WPFUtility.TransFromDataToViewModel(m, _气象数据);
                SendHttpPost(m);

                LogText = "读取气象数据成功";
            }
            else if (!e.IsValid && (e.Msg is RoomSearchMsg || e.Msg is PhecSearch))
            {
                byte id = (byte)e.Msg.GetType().GetProperty("Id").GetValue(e.Msg, null);
                foreach (var item in 温室实时数据集合)
                {
                    if (item.Id == id)
                    {
                        item.检测结果 = ECheckFlag.失败;
                        LogText = string.Format("读取{0}.{1}失败", item.Id, item.RoomName);
                    }
                }
            }
            if (e.Msg is RoomSearchMsg || e.Msg is PhecSearch)
            {
                byte id = (byte)e.Msg.GetType().GetProperty("Id").GetValue(e.Msg, null);
                this.CurrentVmRoom = this.温室实时数据集合.FirstOrDefault(p => p.Id == id);
                RaisePropertyChanged("CurrentVmRoom");
            }
        }

        public RoomDataViewModel CurrentVmRoom { get; set; }

        string LogText { get; set; }

        void SendHttpPost(string uriPath, object sendObject, Action<List<string>> action)
        {
            if (!RC.Current.RootData.启用数据上传)
            {
                return;
            }
            if (string.IsNullOrWhiteSpace(RC.Current.RootData.数据上传地址)
            || string.IsNullOrWhiteSpace(RC.Current.RootData.客户代码))
            {
                return;
            }
            var uri = Regex.Replace(RC.Current.RootData.数据上传地址, @"^(https|http)[^\w]*([\w|\.|\:|\-]*)(.*)", @"$1://$2/") + uriPath;
            List<string> posts = new List<string>();

            sendObject.GetType().GetProperties()
                .ToList()
                .ForEach(p =>
                {
                    var pValue = p.GetValue(sendObject, null);
                    if (pValue != null)
                    {
                        posts.Add(string.Format("{0}={1}", p.Name, pValue));
                    }
                });
            posts.Add("CustomCode=" + RC.Current.RootData.客户代码);
            posts.Add("时间=" + DateTime.Now.ToString());
            if (action != null)
                action(posts);
            var postData = string.Join("&", posts.ToArray());
            httpPostService.AddPost(uri, postData);
        }

        void SendHttpPost(object msg, byte id)
        {
            var room = RC.Current.RootData.温室集合.SingleOrDefault(p => p.Id == id);
            if (room == null)
            {
                return;
            }
            var uriPath = "service/upload";
            SendHttpPost(uriPath, msg, (posts) =>
                {
                    posts.Add("RoomName=" + room.RoomName);
                });
        }

        void SendHttpPost(WeatherStationReturnMsgBase msg)
        {
            var uriPath = "service/uploadws";
            SendHttpPost(uriPath, msg, null);
        }

        public override void Cleanup()
        {
            if (msgReceivedEventHandler != null)
            {
                RC.Current.MsgService.MsgReceived -= msgReceivedEventHandler;
            }
            RC.Current.RootData.RemoveObserver(this);
            base.Cleanup();
        }

        List<ViewModelBase> _Tops = null;
        public List<ViewModelBase> Tops
        {
            get
            {
                if (_Tops == null)
                {
                    _Tops = new List<ViewModelBase>();
#if DEBUG
                    _Tops.Add(GetRoomFullScreen());
#endif

                    _Tops.Add(GetBeginMonitorPort());
                    _Tops.Add(GetEndMonitorPort());
                    if (RC.Current.IsAdmin)
                    {
                        _Tops.Add(GetParams());
                        _Tops.Add(GetWeatherStation());
                        _Tops.Add(GetHistory());
                        _Tops.Add(GetDbLog());
                    }
                    _Tops.Add(GetUsers());
                    _Tops.Add(GetShutdown());
                    _Tops.Add(new VmImage() { Path = Path.Combine(ConfigInfo.RootPath, @"image\company.png") });

                }
                return _Tops;
            }
        }

        private ButtonViewModel GetHistory()
        {
            return new ButtonViewModel("历史数据",
               () =>
               {
                   Messenger.Default.Send<MessageBase>(new MessageBase(), "TopHistory");
               },
               () => true);
        }

        #region ButtonViewModel

        ButtonViewModel GetParams()
        {
            return new ButtonViewModel("参数设置",
                () =>
                {
                    Messenger.Default.Send<MessageBase>(new MessageBase(), "TopOpenParams");
                    WPFUtility.TransFromDataToViewModel(RC.Current.RootData.气象站模似信息, 气象数据);
                },
                () => !监控状态);
        }

        ButtonViewModel GetWeatherStation()
        {
            return new ButtonViewModel("气象站设置",
                () =>
                {
                    Messenger.Default.Send<MessageBase>(new MessageBase(), "TopWeatherStation");
                },
                () => !监控状态);
        }

        ButtonViewModel GetShutdown()
        {
            return new ButtonViewModel("退出系统",
               () =>
               {

                   Messenger.Default.Send<MessageBase>(new MessageBase(), "TopShutdown");
               },
               () => true);
        }

        ButtonViewModel GetBeginMonitorPort()
        {
            return new ButtonViewModel("开始监控",
               () =>
               {
                   监控状态 = !监控状态;
                   this.ErrorText = "";
                   this.LogText = "";
               },
               () => !监控状态);
        }

        ButtonViewModel GetEndMonitorPort()
        {
            return new ButtonViewModel("结束监控",
               () =>
               {
                   监控状态 = !监控状态;
               },
               () => 监控状态);
        }

        ButtonViewModel GetRoomCoerce()
        {
            return new ButtonViewModel("TestRoomCoerce",
               () =>
               {
                   ASoft.Msg.RoomCoerceStartMsg msg = new Msg.RoomCoerceStartMsg() { Id = 1 };
                   RC.Current.MsgService.SendMsg(msg);
               },
               () => 监控状态);
        }

        ButtonViewModel GetDbLog()
        {
            return new ButtonViewModel("数据日志",
                () =>
                {
                    Messenger.Default.Send<MessageBase>(new MessageBase(), "DbLog");
                },
                () => true);
        }

        ButtonViewModel GetRoomFullScreen()
        {
            return new ButtonViewModel("模拟界面",
                () =>
                {
                    Messenger.Default.Send<MessageBase>(new MessageBase(), "RoomFullScreen");
                },
                () => true);
        }


        ButtonViewModel GetUsers()
        {
            return new ButtonViewModel("用户管理",
                () =>
                {
                    Messenger.Default.Send<MessageBase>(new MessageBase(), "Users");
                },
                () => true);
        }


        #endregion

        public const string 监控状态PropertyName = "监控状态";

        public bool 监控状态
        {
            get
            {
                return RC.Current.IsMonitoring;
            }

            set
            {
                if (RC.Current.IsMonitoring == value)
                {
                    return;
                }

                var oldValue = RC.Current.IsMonitoring;
                if (value)
                {
                    if (!RC.Current.SerialPortService.IsOpen)
                    {
                        RC.Current.SerialPortService.OpenPort();
                    }
                    MyTaskService.Current.Start((e) =>
                        {
                            Messenger.Default.Send<Exception>(e, "taskException");
                        });
                }
                else
                {
                    MyTaskService.Current.Stop();
                    Thread.Sleep(2000);
                    if (RC.Current.SerialPortService.IsOpen)
                    {
                        RC.Current.SerialPortService.ClosePort();
                    }
                }
                RC.Current.IsMonitoring = value;
                RC.Current.IsMonitoring = value;
                RC.Current.Loger.Trace(string.Format("监控状态:{0}", 监控状态));
                RaisePropertyChanged(监控状态PropertyName);
            }
        }

        #region 温室实时数据集合

        ObservableCollection<RoomDataViewModel> _温室实时数据集合;
        public ObservableCollection<RoomDataViewModel> 温室实时数据集合
        {
            get
            {
                if (_温室实时数据集合 == null)
                {
                    _温室实时数据集合 = new ObservableCollection<RoomDataViewModel>();
                }
                if (_温室实时数据集合.Count == 0)
                {
                    Reload温室实时数据集合();
                }
                return _温室实时数据集合;
            }
        }

        public ObservableCollection<RoomDataViewModel> _OnlyRoom实时数据集合;
        public ObservableCollection<RoomDataViewModel> OnlyRoom实时数据集合
        {
            get
            {
                if (_OnlyRoom实时数据集合 == null)
                {
                    _OnlyRoom实时数据集合 = new ObservableCollection<RoomDataViewModel>();
                }
                if (温室实时数据集合.Count == 0)
                {
                    Reload温室实时数据集合();
                }
                return _OnlyRoom实时数据集合;
            }
        }

        public ObservableCollection<RoomDataViewModel> _OnlyPhec实时数据集合;
        public ObservableCollection<RoomDataViewModel> OnlyPhec实时数据集合
        {
            get
            {
                if (_OnlyPhec实时数据集合 == null)
                {
                    _OnlyPhec实时数据集合 = new ObservableCollection<RoomDataViewModel>();
                }
                if (温室实时数据集合.Count == 0)
                {
                    Reload温室实时数据集合();
                }
                return _OnlyPhec实时数据集合;
            }
        }

        public void Reload温室实时数据集合()
        {
            if (_温室实时数据集合 != null)
            {
                _温室实时数据集合.Clear();
            }
            else
            {
                _温室实时数据集合 = new ObservableCollection<RoomDataViewModel>();
            }

            if (_OnlyRoom实时数据集合 != null)
            {
                _OnlyRoom实时数据集合.Clear();
            }
            else
            {
                _OnlyRoom实时数据集合 = new ObservableCollection<RoomDataViewModel>();
            }

            if (_OnlyPhec实时数据集合 != null)
            {
                _OnlyPhec实时数据集合.Clear();
            }
            else
            {
                _OnlyPhec实时数据集合 = new ObservableCollection<RoomDataViewModel>();
            }

            RC.Current.RoomLastMsgs.Clear();

            if (!IsInDesignMode)
            {
                RC.Current.RootData.温室集合.ForEach(p =>
                {
                    if (!RC.Current.RootData.IgnoreRoomIds.Contains(p.Id))
                    {
                        var vm = new RoomDataViewModel(p);
                        _温室实时数据集合.Add(vm);
                        if (vm.IsPhec)
                        {
                            _OnlyPhec实时数据集合.Add(vm);
                        }
                        else
                        {
                            _OnlyRoom实时数据集合.Add(vm);
                        }
                    }
                });
            }
        }

        #endregion

        #region Test
        void TestStart()
        {
            RC.Current.TcpService.IP = "192.168.40.128";
            RC.Current.TcpService.Port = 6020;
            Thread thread = new Thread(new ThreadStart(TestThreadStart));
            thread.IsBackground = true;
            thread.Start();
        }

        void TestThreadStart()
        {
            while (true)
            {
                var msg = RC.Current.TcpService.Receive();
                RC.Current.TcpService.Send(new WeatherStationReturnSearchMsg().GetData());
            }
        }

        #endregion


        WeatherStationInfoMsgViewModelBase _气象数据;
        public WeatherStationInfoMsgViewModelBase 气象数据
        {
            get
            {
                if (_气象数据 == null)
                {
                    _气象数据 = new WeatherStationInfoMsgViewModelBase();
                    if (IsInDesignMode)
                    {
                        return _气象数据;
                    }
                    WPFUtility.TransFromDataToViewModel(RC.Current.RootData.气象站模似信息, _气象数据);
                    _气象数据.检测结果 = RC.Current.RootData.启用模似气象站 ? ECheckFlag.模似 : ECheckFlag.未检测;
                }
                return _气象数据;
            }
        }

        #region "StatusText"

        public string StatusText
        {
            get
            {
                return string.Format("{0},串口信息:{1},串口:{2},温室:{3},气象站:{4},日志:{5}",
                    DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    RC.Current.SerialPortService.ToString(),
                    RC.Current.SerialPortService.IsOpen ? "打开" : "关闭",
                    this.监控状态 ? "正在监控" : "停止监控",
                    RC.Current.RootData.启用模似气象站
                    ? "模似数据"
                    : RC.Current.RootData.气象站实时信息 == null
                        ? "气象数据异常(温室停止发送、接收数据)"
                        : "实时数据",
                    string.IsNullOrWhiteSpace(LogText) ? "无" : LogText);
            }

        }

        public void RaiseStatusTextChanged()
        {
            RaisePropertyChanged("StatusText");
        }

        #endregion


        #region "ErrorText"

        private string _ErrorText = default(string);

        public string ErrorText
        {
            get
            {
                return _ErrorText;
            }
            set
            {
                if (_ErrorText == value)
                {
                    return;
                }
                _ErrorText = value;
                RaisePropertyChanged("ErrorText");
            }
        }

        #endregion


        public void SetData(RootData data, EObserverType observerType)
        {
            if (observerType == EObserverType.气象站实时信息)
            {
                if (data.气象站实时信息 == null)
                {
                    this.气象数据.大风报警位 = 0;
                    this.气象数据.风速 = 0;
                    this.气象数据.风向 = 0;
                    this.气象数据.光照 = 0;
                    this.气象数据.室外湿度 = 0;
                    this.气象数据.室外温度 = 0;
                    this.气象数据.雨雪 = 0;
                }
                else
                {
                    WPFUtility.TransFromDataToViewModel(RC.Current.RootData.气象站实时信息, _气象数据);
                }
            }
        }
    }
}